package com.example.social.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.social.dto.CommentDTO;
import com.example.social.dto.PostDTO;
import com.example.social.entity.Comment;
import com.example.social.entity.Post;
import com.example.social.entity.User;
import com.example.social.mapper.CommentMapper;
import com.example.social.mapper.PostMapper;
import com.example.social.mapper.UserMapper;
import com.example.social.service.PostLikeService;
import com.example.social.service.PostService;
import com.example.social.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.social.common.BusinessException;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

    private final UserService userService;
    private final UserMapper userMapper;
    private final PostLikeService postLikeService;
    private final CommentMapper commentMapper;

    @Override
    @Transactional
    public PostDTO createPost(String content, List<String> images) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userService.getByUsername(username);

        // 创建动态
        Post post = new Post();
        post.setUserId(user.getId());
        post.setContent(content);
        post.setImages(images);
        post.setLikeCount(0);
        post.setCommentCount(0);

        // 保存动态
        save(post);

        // 转换为DTO
        return convertToDTO(post, user);
    }

    @Override
    public IPage<PostDTO> getPosts(Long page, Long size) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User currentUser = userService.getByUsername(username);

        // 分页查询
        Page<Post> postPage = new Page<>(page, size);
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Post::getCreateTime);
        
        IPage<Post> postIPage = page(postPage, wrapper);

        // 转换为DTO
        return postIPage.convert(post -> {
            User postUser = userMapper.selectById(post.getUserId());
            post.setUser(postUser);
            return convertToDTO(post, currentUser);
        });
    }

    @Override
    @Transactional
    public void toggleLike(Long postId) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userService.getByUsername(username);

        // 切换点赞状态
        boolean isLiked = postLikeService.toggleLike(postId, user.getId());
        
        // 更新点赞数
        Post post = getById(postId);
        post.setLikeCount(post.getLikeCount() + (isLiked ? 1 : -1));
        updateById(post);
    }

    @Override
    @Transactional
    public void comment(Long postId, String content) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = userService.getByUsername(username);

        // 更新评论数
        Post post = getById(postId);
        post.setCommentCount(post.getCommentCount() + 1);
        updateById(post);

        // 保存评论
        Comment comment = new Comment();
        comment.setUserId(user.getId());
        comment.setPostId(postId);
        comment.setContent(content);
        commentMapper.insert(comment);
    }

    @Override
    public List<CommentDTO> getComments(Long postId) {
        // 查询评论列表
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getPostId, postId)
                .orderByDesc(Comment::getCreateTime);
        
        List<Comment> comments = commentMapper.selectList(wrapper);
        
        // 转换为DTO
        return comments.stream()
                .map(comment -> {
                    User user = userMapper.selectById(comment.getUserId());
                    return convertToCommentDTO(comment, user);
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void deleteComment(Long commentId) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User currentUser = userService.getByUsername(username);

        // 获取评论
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new BusinessException("评论不存在");
        }

        // 检查是否是评论作者
        if (!comment.getUserId().equals(currentUser.getId())) {
            throw new BusinessException("无权删除该评论");
        }

        // 更新评论数
        Post post = getById(comment.getPostId());
        post.setCommentCount(post.getCommentCount() - 1);
        updateById(post);

        // 删除评论
        commentMapper.deleteById(commentId);
    }

    private PostDTO convertToDTO(Post post, User currentUser) {
        PostDTO dto = new PostDTO();
        BeanUtils.copyProperties(post, dto);
        
        // 设置用户信息
        if (post.getUser() != null) {
            dto.setUser(userService.convertToDTO(post.getUser()));
        }
        
        // 检查当前用户是否点赞
        if (currentUser != null) {
            dto.setLiked(postLikeService.hasLiked(post.getId(), currentUser.getId()));
        }
        
        return dto;
    }

    private CommentDTO convertToCommentDTO(Comment comment, User user) {
        CommentDTO dto = new CommentDTO();
        BeanUtils.copyProperties(comment, dto);
        
        // 设置用户信息
        if (user != null) {
            dto.setUser(userService.convertToDTO(user));
        }
        
        return dto;
    }
} 